home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / pt20pc.zip / LINES.C < prev    next >
C/C++ Source or Header  |  1991-02-04  |  9KB  |  351 lines

  1. #include "pt.h"
  2.  
  3. int pascal
  4. /* XTAG:movenl */
  5. movenl(addr, len, buffer, makeLowerCase)
  6.     unsigned char far *addr;
  7.     unsigned char *buffer;
  8.     register int len;
  9.     int makeLowerCase;
  10. {
  11.     register unsigned char ch;
  12.  
  13.     while( len-- > 0 ) {
  14.         ch = *addr++;
  15.         if( makeLowerCase && 'A' <= ch && ch <= 'Z' )
  16.             ch += 'a' - 'A';
  17.         *buffer++ = ch;
  18.         if( ch == '\n' )
  19.             return len;
  20.     }
  21.     return -1;
  22. }
  23.  
  24. long pascal
  25. /* XTAG:readLine */
  26. readLine(fileId, cp, buffer, makeLowerCase)
  27.     int fileId, makeLowerCase;
  28.     long cp;
  29.     unsigned char *buffer;
  30. {
  31.     extern struct openFile *files;
  32.     extern unsigned char msgBuffer[];
  33.     extern int debug;
  34.  
  35.     static int iBuffer, iCount;
  36.     int len, left, incr, eof;
  37.     long loBuf, hiBuf;
  38.     register unsigned char ch;
  39.     unsigned char far *addrBuf;
  40.     unsigned char far *firstByte;
  41.     unsigned char far *dummy;
  42.     unsigned char **fp;
  43.     register struct openFile *ff;
  44.  
  45. /* see if the file is there */
  46. if( fileId == -1 ) {
  47.     buffer[0] = 0;
  48.     return 0L;
  49. }
  50.  
  51. /* for efficiency, keep some addresses */
  52. ff = &files[fileId];
  53.  
  54. if( ff->origHandle == -1 ) {
  55.     buffer[0] = 0;
  56.     return 0L;
  57. }
  58.  
  59. /* see if the logical byte number is invalid */
  60. if( cp < 0 ) {
  61.     sprintf(msgBuffer,
  62.         "readLine: character pointer is negative (%ld)", cp);
  63.     msg(msgBuffer, 3);
  64.     return 0L;
  65. } else if( cp >= ff->fileSize) {
  66.     buffer[0] = 0;
  67.     return ff->fileSize;
  68. }
  69.  
  70. /* iBuffer is the next free byte in the buffer */
  71. iBuffer = 0;
  72. iCount = 0;
  73.  
  74. /* this loop gets the characters one per loop iteration */
  75. /* these three variables are for quick access to structure parts */
  76. loBuf = ff->loLogBuffer;
  77. hiBuf = ff->hiLogBuffer;
  78. /* addrBuf is set to avoid doing the long subtraction in the loop */
  79. fp = (unsigned char **)&addrBuf;
  80. *fp = ff->logBufOffset + (unsigned int)(cp - loBuf);
  81. *++fp = ff->logBufSegment;
  82.  
  83. while( iBuffer < (MSGBUFFERSIZE - 1) ) {
  84.     /* check for optimized special cases */
  85.     if( loBuf <= cp && cp <= hiBuf ) {
  86.         /* find out how many bytes left in the buffer */
  87.         len = (int)(hiBuf - cp) + 1;
  88.         if( (len + iBuffer) > MSGBUFFERSIZE )
  89.             len = MSGBUFFERSIZE - iBuffer - 1;
  90.         /* do a fast scan for a newline in the buffer */
  91.         left = movenl(addrBuf, len, &buffer[iBuffer], makeLowerCase);
  92.         if( left < 0 ) {    /* no newline was moved into buffer */
  93.             cp += len;    /* move past buffer */
  94.             addrBuf += len;
  95.             iBuffer += len;    /* move moved 'len' chars */
  96.             continue;    /* else will hit next (cp>hiBuf) */
  97.         } else {        /* found nl */
  98.             incr = len - left;
  99.             cp += incr;     /* move past it */
  100.             break;
  101.         }
  102.     } else {
  103.         eof = getSpan(fileId, cp, &firstByte, &dummy, 0);
  104.         if( eof ) {
  105.             buffer[iBuffer++] = 0;
  106.             break;
  107.         }
  108.         ch = *firstByte;
  109.         /* the getSpan will have changed these */
  110.         loBuf = ff->loLogBuffer;
  111.         hiBuf = ff->hiLogBuffer;
  112.         /* +1 since we just read ch */
  113.         fp = (unsigned char **)&addrBuf;
  114.         *fp = ff->logBufOffset + (int)(cp + 1 - loBuf);
  115.         *++fp = ff->logBufSegment;
  116.     }
  117.     ++cp;
  118.     if( makeLowerCase && 'A' <= ch && ch <= 'Z' )
  119.         ch += 'a' - 'A';
  120.     buffer[iBuffer++] = ch;
  121.     if( ch == '\n' )
  122.         break;
  123. }
  124. /* buffer[iBuffer] = '\0'; */
  125. return cp;
  126. }
  127.  
  128. int pascal
  129. /* XTAG:next1nl */
  130. next1nl(addr, len)
  131.     unsigned char far *addr;
  132.     register int len;
  133. {
  134.     while( len-- > 0 )
  135.         if( *addr++ == '\n' )
  136.             return len;
  137.     return -1;
  138. }
  139.  
  140. long pascal
  141. /* XTAG:nextLine */
  142. nextLine(fileId, cp, n)
  143.     int fileId, *n;
  144.     long cp;
  145. {
  146.     extern struct openFile *files;
  147.     extern unsigned char msgBuffer[];
  148.     extern int debug;
  149.  
  150.     long loBuf, hiBuf, oldcp;
  151.     register unsigned char ch;
  152.     unsigned char far *addrBuf;
  153.     unsigned char far *firstByte;
  154.     unsigned char far *dummy;
  155.     struct longPointer *fp;
  156.     register struct openFile *ff;
  157.     int nLines, len, left, incr, eof;
  158.  
  159. /* see if the file is there */
  160. if( fileId == -1 )
  161.     return cp;
  162.  
  163. /* for efficiency, keep some addresses */
  164. ff = &files[fileId];
  165.  
  166. if( ff->origHandle == -1 ) {
  167.     *n = 0;
  168.     return 0L;
  169. }
  170.  
  171. /* see if the logical byte number is invalid */
  172. if( cp < 0 ) {
  173.     sprintf(msgBuffer,
  174.         "nextLine: invalid character pointer = %ld  fileId=%d  *n=%d",
  175.         cp, fileId, *n);
  176.     msg(msgBuffer, 3);
  177.     *n = 0;
  178.     return 0L;
  179. } else if( cp >= ff->fileSize ) {
  180.     *n = 0;
  181.     return ff->fileSize;
  182. }
  183.  
  184. /* this loop get the characters one per loop iteration */
  185. /* these three variables are for speedy access to structure parts */
  186. loBuf = ff->loLogBuffer;
  187. hiBuf = ff->hiLogBuffer;
  188.  
  189. /* addrBuf is set to avoid doing the long subtraction in the loop */
  190. fp = (struct longPointer *)&addrBuf;
  191. fp->offset = ff->logBufOffset + (int)(cp - loBuf);
  192. fp->segment = ff->logBufSegment;
  193.  
  194. nLines = 0;
  195. while( nLines < *n ) {
  196.     oldcp = cp;
  197.     ch = 0;
  198.     while( ch != '\n' ) {
  199.         /* check for optimized special cases */
  200.         if( loBuf <= cp && cp <= hiBuf ) {
  201.             /* find out how many bytes left in the buffer */
  202.             len = (int)(hiBuf - cp) + 1;
  203.             /* do a fast scan for a newline in the buffer */
  204.             left = next1nl(addrBuf, len);
  205.             if( left < 0 ) {    /* no newline in buffer */
  206.                 cp += len;    /* move past buffer */
  207.                 ch = 0;        /* any non-nl char will do */
  208.             } else {        /* found nl */
  209.                 incr = len - left;
  210.                 cp += incr;     /* move past it */
  211.                 addrBuf += incr; /* adjust this too */
  212.                 break;
  213.             }
  214.         } else {
  215.             eof = getSpan(fileId, cp++, &firstByte, &dummy, 0);
  216.             /* increment cp since we already have 'ch' */
  217.             if( eof ) {    /* end of file */
  218.                 if( oldcp < --cp ) /* no CRLF at EOF */
  219.                     ++nLines;
  220.                 goto ret;
  221.             }
  222.             ch = *firstByte;
  223.             /* the getSpan will have changed these */
  224.             loBuf = ff->loLogBuffer;
  225.             hiBuf = ff->hiLogBuffer;
  226.             fp = (struct longPointer *)&addrBuf;
  227.             fp->offset = ff->logBufOffset + (int)(cp - loBuf);
  228.             fp->segment = ff->logBufSegment;
  229.         }
  230.     }
  231.     ++nLines;
  232. }
  233. ret:
  234. *n = nLines;
  235. return cp;
  236. }
  237.  
  238. int pascal
  239. /* XTAG:prev1nl */
  240. prev1nl(addr, len)
  241.     unsigned char far *addr;
  242.     register int len;
  243. {
  244.     while( len-- > 0 )
  245.         if( *addr-- == '\n' )
  246.             return len;
  247.     return -1;
  248. }
  249.  
  250. long pascal
  251. /* XTAG:prevLine */
  252. prevLine(fileId, cp, n)
  253.     int fileId, *n;
  254.     long cp;
  255. {
  256.     extern unsigned char msgBuffer[];
  257.     extern struct openFile *files;
  258.     extern int debug;
  259.  
  260.     long loBuf, hiBuf, oldcp;
  261.     register unsigned char ch;
  262.     unsigned char far *addrBuf;
  263.     struct longPointer *fp;
  264.     register struct openFile *ff;
  265.     int nLines, len, left, decr;
  266.  
  267. /* see if the file is there */
  268. if( fileId == -1 )
  269.     return cp;
  270.  
  271. /* for efficiency, keep some addresses */
  272. ff = &files[fileId];
  273.  
  274. if( ff->origHandle == -1 ) {
  275.     *n = 0;
  276.     return 0L;
  277. }
  278. /* see if the logical byte number is invalid */
  279. if( cp < 0 ) {
  280.     sprintf(msgBuffer,
  281.         "prevLine: invalid character pointer = %ld  fileId=%d  *n=%d",
  282.         cp, fileId, *n);
  283.     msg(msgBuffer, 3);
  284.     *n = 0;
  285.     return 0L;
  286. }
  287.  
  288. /* move past the '\n' unless the search is for the beginning of the line */
  289. if( *n >= 0 )
  290.     cp -= 2;
  291. else {    /* just find the beginning of this line */
  292.     /* this works even when you are already at the beginning */
  293.     *n = 1;
  294.     /* do this so it also works sitting on the '\n' */
  295.     if( readChar(fileId, cp) == '\n' )
  296.         --cp;
  297. }
  298.  
  299. /* this loop get the characters one per loop iteration */
  300. /* these three variables are for speedy access to structure parts */
  301. loBuf = ff->loLogBuffer;
  302. hiBuf = ff->hiLogBuffer;
  303. /* addrBuf is set to avoid doing the long subtraction in the loop */
  304. fp = (struct longPointer *)&addrBuf;
  305. fp->offset = ff->logBufOffset + (int)(cp - loBuf);
  306. fp->segment = ff->logBufSegment;
  307.  
  308. nLines = 0;
  309. while( nLines < *n ) {
  310.     oldcp = cp;
  311.     ch = 0;
  312.     while( ch != '\n' ) {
  313.         /* check for optimized special cases */
  314.         if( loBuf <= cp && cp <= hiBuf ) {
  315.             /* find out how many bytes left in the buffer */
  316.             len = (int)(cp - loBuf) + 1;
  317.             /* do a fast scan for a newline in the buffer */
  318.             left = prev1nl(addrBuf, len);
  319.             if( left < 0 ) {    /* no newline in buffer */
  320.                 cp -= len;    /* move past buffer */
  321.                 ch = 0;        /* any non-nl char will do */
  322.             } else {        /* found nl */
  323.                 decr = len - left;
  324.                 cp -= decr;     /* move past it */
  325.                 addrBuf -= decr; /* adjust this too */
  326.                 break;
  327.             }
  328.         } else {
  329.             ch = readChar(fileId, cp--);
  330.             /* decrement cp since we already have 'ch' */
  331.             if( ch == 0 && cp < 0 ) {    /* beginning of fil